import { IRawMsg } from "@/chatlog_types/IRawMsg";
import { GlobalValue } from "@/GlobalValue";
import { Chat } from "@/views/Chat";
import axios, { isAxiosError } from "axios";
import dayjs from "dayjs";
import { MessageLoader } from "./MessageLoader";
import { msg_adapter } from "./msg_adapter";
import { BaseChatMgr } from "./BaseChatMgr";

export class LocalMessageLoader extends MessageLoader {
  static readonly TAG: string = 'LocalMessageLoader';
  readonly TAG: string = LocalMessageLoader.TAG

  /**
   * 每次拉取多少条新消息
   *
   * @private
   * @type {number}
   * @memberof LocalMessageLoader
   */
  private _news_limit: number = 50;

  /**
   * 新消息偏移值
   *
   * @private
   * @type {number}
   * @memberof LocalMessageLoader
   */
  private _news_offset: number = 0;

  /**
   * 新消息请求起点日期
   * 
   * @private
   * @type {string}
   * @memberof LocalMessageLoader
   */
  private _news_start_date: string = ''


  private page_size: number;
  private page_idx: number = 0;
  constructor(mgr: BaseChatMgr, page_size: number = 50) {
    super(mgr)
    this.page_size = page_size
  }
  override reset(): void {
    this.page_size = 50;
    this.page_idx = 0;
  }

  override async load_news(): Promise<Chat.Message<IRawMsg>[]> {
    const { owner } = this;
    const latest_msg = owner.latest?.raw;
    if (!latest_msg) return Promise.resolve([]);

    const http_addr = GlobalValue.current_state.chatlog_state?.http_addr
    if (!http_addr) return Promise.resolve([]);

    const end_date = dayjs().format('YYYY-MM-DD');
    const start_date = dayjs(latest_msg!.time).format('YYYY-MM-DD');

    if (start_date !== this._news_start_date) {
      this._news_start_date = start_date;
      this._news_offset = 0;
    }
    const { session: { userName: talker } } = owner;
    const params = {
      format: 'json',
      time: `${start_date}~${end_date}`,
      talker: talker,
      limit: this._news_limit,
      offset: this._news_offset,
      asc: true
    }
    const url = `http://${http_addr}/api/v1/chatlog`
    return axios(url, { responseType: 'json', params })
      .then((r: { data: { items: IRawMsg[], account: string } } | undefined) => {
        const list = Array.isArray(r?.data.items) ? r.data.items.map(v => msg_adapter(v, r.data.account, http_addr)) : []
        if (!list.length) return [];
        const msgs: Chat.Message<IRawMsg>[] = []
        let anchor_found = false;
        for (let i = 0; i < list.length; ++i) {
          const item = list[i];
          if (anchor_found) {
            msgs.push(item);
            continue;
          } else if (item.raw?.seq === latest_msg.seq) {
            anchor_found = true;
            this._news_offset += i;
          }
        }
        if (!anchor_found) {
          this._news_offset += list.length;
          return [];
        }
        if (msgs[0])
          msgs[0]!.showTime = true
        return msgs;
      }).catch((e) => {
        return Promise.reject(
          isAxiosError(e) && typeof e.response?.data === 'string' ?
            new Error(`[${e.response.status}]${e.response?.data}`) : e
        );
      })
  }

  override async load_history(): Promise<Chat.Message<IRawMsg>[]> {
    const http_addr = GlobalValue.current_state.chatlog_state?.http_addr
    if (!http_addr) return [];
    const { session: { userName: talker } } = this.owner;
    const { page_idx, page_size } = this;
    const start_date_text = this.owner.start_date.format('YYYY-MM-DD');
    const end_date_text = this.owner.end_date.format('YYYY-MM-DD');
    const params = {
      format: 'json',
      time: `${start_date_text}~${end_date_text}`,
      talker: talker,
      limit: page_size,
      offset: page_idx * page_size,
      asc: false
    }
    const abort_ctrl = new AbortController();
    const url = `http://${http_addr}/api/v1/chatlog`
    const r: any = await axios(url, { responseType: 'json', params, signal: abort_ctrl.signal })
    return Array.isArray(r?.data.items) ? r.data.items.map((v: any) => msg_adapter(v, r.data.account, http_addr)) : []
  }

  override on_history_accepted(): void {
    this.page_idx++;
  }
}